#!/usr/bin/python
# coding: utf-8

import sys
from math import log
from optparse import Option, OptionParser

ALPHABET = 'actg'

##
## Bessel representation
## http://functions.wolfram.com/Bessel-TypeFunctions/BesselK/21/01/01/
## indefinite integral of K0 : 0.5 * pi * z * (kv(0,z) * struve(-1,z) + kv(1,z) * struve(0,z))
## P(Z>z) = 0.5 * z * (kv(0,z) * struve(-1,z) + kv(1,z) * struve(0,z))
##

##
## EUC = 0.577215665
##
##
def fact(k):
    r = 1.0
    for i in xrange(1, k+1):
        r = r * i
    return r

from math import log
EUC = 0.577215665

## Approximate:
## http://www.convertit.com/Go/ConvertIt/Reference/AMS55.ASP?Res=200&Page=480
## Table values:
## http://www.convertit.com/Go/ConvertIt/Reference/AMS55.ASP?Res=150&Page=492

def iK(x, n):
    x = float(x)
    s1 = - x * (EUC + log(x/2)) * sum(((x/2)**(2*k))/(fact(k)**2 * (2*k+1)) for k in xrange(n+1))
    s2 = x * sum(((x/2)**(2*k))/(fact(k)**2 * (2*k+1)**2) for k in xrange(n+1))
    s3 = x * sum(((x/2)**(2*k))/(fact(k)**2 * (2*k+1))*(sum(1.0/i for i in xrange(1, k+1))) for k in xrange(1,n+1))
    print s1,s2,s3
    return s1 + s2 + s3


def clog(f):
    if f > 0:
        return f * log(f)
    else:
        return 0.0

def mutual_inf_mx(m1, m2):
    I = 0
    for j in [0,1,2]:
        y1, y2 = 0, 0
        for c in ALPHABET:
            w1 = m1[j][c]
            w2 = m2[j][c]
            y1 += w1
            y2 += w2
            I += clog(w1) + clog(w2) - clog(w1 + w2)
        I += clog(y1 + y2) - clog(y1) - clog(y2)
    return I

def create_mx(seq):
    d = dict((i, dict((c,0) for c in ALPHABET)) for i in [0,1,2])
    for i, c in enumerate(seq):
        d[i][c] += 1
    print seq
    return d

def find(seq, options):
    reward     = options.reward
    penalty    = options.penalty
    win_length = options.win_length
    length     = len(seq)
    seq        = seq.lower()
    
    for x in xrange(win_length, length-win_length-1):
        print x
        mx_prev = create_mx(seq[x-win_length:x])
        mx_1    = create_mx(seq[x:x+win_length])
        print mutual_inf_mx(mx_prev, mx_1)
        mx_2    = create_mx(seq[x+1:x+1+win_length])
        print mutual_inf_mx(mx_prev, mx_2)
        mx_3    = create_mx(seq[x+2:x+2+win_length])
        print mutual_inf_mx(mx_prev, mx_3)


if __name__ == '__main__':
    parser = OptionParser(usage='%prog [-r REWARD -p PENALTY -l WIN_LENGTH -s SEQUENCE]')
    parser.add_option(Option(
        '-r', '--reward',
        dest = 'reward',
        type = int,
        default = 1,
    ))
    parser.add_option(Option(
        '-p', '--penalty',
        dest = 'penalty',
        type = int,
        default = 3,
    ))
    parser.add_option(Option(
        '-l', '--window-length',
        dest = 'win_length',
        type = int,
        default = 36,
    ))
    parser.add_option(Option(
        '-s', '--sequence',
        dest = 'sequence',
    ))
    opts, args = parser.parse_args()
    if opts.win_length % 3 != 0:
        print >> sys.stderr, "WIN_LENGTH is not divided by 3"
        sys.exit(1)
        
    if opts.sequence:
        find(opts.sequence, opts)
    else:
        for line in sys.stdin:
            find(line.strip(), opts)
